Skip to content

feat(pm): census the open cards whose named changeset target is already consumed - #17245

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-16850-changeset-deadline-census
Sep 9, 2026
Merged

feat(pm): census the open cards whose named changeset target is already consumed#17245
baozhoutao merged 1 commit into
mainfrom
claude/issue-16850-changeset-deadline-census

Conversation

@claude

@claude claude Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #16850

Clause-②: no
skip-changeset: root package.json is "private": true, and the other two paths are scripts/pm/** and .github/workflows/** — nothing any package's files[] ships moves.

What this lands

The detection half of #16850, report-only: scripts/pm/changeset-deadline-census.mjs.

A card whose deliverable is one line in a pending .changeset/*.md carries a hard deadline that nothing measured. Once a release compiles the file into packages/PKG/CHANGELOG.md the one-line edit is gone, while the card's prose goes on asserting the file is "still pending" forever — prose does not re-measure itself.

The dispatch ruling took the card's option 1 and this lane's standing rule verbatim:

⚠️ report-only first, the census is the deliverable, expansion only when the census reads zero including its blind spot.

⇒ ⛔ Option 2 (fail the release on an open card naming a changeset it is about to consume) is not taken: the card itself says it "puts the backlog on the release path, which is a real cost that must be argued, not assumed". ⛔ Option 3 (correct at filing time) is not taken: #15058's body records why its source PR could not ride the edit in place.

⛔ Nothing here fails a build. The population — issue bodies — is a new scan population, so it is censused before anything is enforced. Only the offline --self-test runs in CI.

⭐ The census — the deliverable

Taken 2026-09-09 against origin/main = 87ad73b062, .changeset/ corpus 53 files, 619 open issues scanned (27 open PRs filtered out):

⭐ CENSUS: 10 open card(s) name 14 concrete .changeset/*.md path(s).
   verdicts: not-landed-since-filed 1 · consumed 11 · window-open 1 · permanent 1
   exposed (absent, not sha-pinned): 10
   of those, asserting pendency in prose the tree has falsified: 5

Read by hand, of the ten cards only four are members of the class the card describes — a card whose deliverable IS a line in a pending changeset. Their state today:

card target state
#16859 permissions-block-named-refusal.md CONSUMED — the body says verbatim "is on main and still unconsumed"
#17026 seed-locale-axis.md CONSUMED — filed 2026-09-09T02:57 naming it as held by the release PR; gone by 21:4xZ
#16850 stack-refusal-envelopes.md (#16671's target) CONSUMED — the third instance the card predicted
#17167 operator-facing-raw-exec-cause-text.md not-landed-since-filed — its PR #17073 is still open+draft, so the window has not opened yet

The instance count is five, not three. #16859 and #17026 are two further silent expiries, both of which happened while #16850 sat in the queue. The remaining six cards cite a changeset as precedent, as a reading-table value or as provenance; they carry no deadline. ⛔ Nothing is live-and-exposed today: the one window-open row (#17003) names its path inside a quoted git diff --stat listing, not as a deliverable.

⚠️ The measuring trap, and the controls that answer it

The card names it and this file obeys it:

The card's words, with its angle-bracket placeholders respelled so GitHub's body sanitizer cannot eat them: git ls-tree REF -- PATH exits 0 even when nothing matches, so an && echo PRESENT idiom reports PRESENT for a file that does not exist.

⛔ No verdict here reads an exit code. Presence is a line count of git show REF:PATH, corroborated against one .changeset/ listing read per run — two instruments, neither a status. Every run establishes three controls before it judges a row, and REFUSES (exit 3) if any fails, because with a broken reader every row reads "consumed":

corpus    the .changeset/ listing is non-empty
positive  .changeset/README.md is in the listing AND reads >= 1 line
negative  a synthetic path is absent from the listing AND reads 0 lines

Absent is not consumed. An absent target may live on an unmerged PR branch or be proposed, and calling those "consumed" would inflate the very number the census reports. So an absent path is asked whether it landed (git log --diff-filter=A), and the answer is accepted only inside a history horizon proved by historyHorizon() — anchored per row on the card's own filing date, because agent containers clone shallow and a shallow git log answers from truncated history at exit 0 with no warning. Outside the horizon the row is inconclusive and the run exits 2, so "not measured" cannot be read as "clean".

What a machine cannot decide, printed by every run

⚠️ A mention is not a deliverable. Six of the ten rows above prove it. Nothing in a body scan separates a deliverable from a citation, and this file does not pretend to — it reports the state of the PATH and leaves intent to the reader. Two mechanical refinements narrow the noise without judging intent: a mention prefixed by a commit sha is bucketed as pinned-to-history, and a body that also asserts pendency in so many words is flagged asserts-pending. That flag is a HINT with a silent false-negative direction (#17026 carries the deadline and matches no phrase) and a false-positive one (#16973's "pending changeset" is an unrelated sentence) — ⛔ never a verdict. Every run prints its blind spots: bodies only, this board only, mention-is-not-deliverable, window-open means the file exists rather than the sentence being correct, and the hint's direction.

Does the number justify an exit contract?

Not today, and the census is why. The number is not zero — the class is real and it has now failed five times — but every exposed row is a card whose window is already closed, so a gate switched on now would red on history nobody can act on. What the number does justify is exactly what landed: a runnable census a seat takes before a release, plus the standing observation that the one row worth watching (#17167) becomes exposed the moment PR #17073 merges. An exit contract is worth re-opening when a run finds a window-open row that IS a deliverable — the state this census has never yet observed.

Verification

  • pnpm check:pm-changeset-deadline-census — self-test green, 5 batteries, roster floor enforced.
  • node scripts/pm/dispatch-gates.mjs --ran62 derived, 62 run, 0 NOT-MEASURED, 0 UNRUN.
  • pnpm exec eslint . --no-inline-config --format json at 91a204865a6444 files, 0 errors, 0 warnings (whole tree, not narrowed).
  • Five derived gates returned exit 3 = PREREQUISITE NOT MET (check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content, check:type-check-debt): each reads built dist/, which this worktree has not built. ⛔ Read as NOT MEASURED, not as green and not as red — and none of them can move on this diff, whose three paths are input to no package build.
  • grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' over all three changed files — no hits.

验收备注

🤖 Generated with Claude Code

https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU


Generated by Claude Code

…dy consumed

A card whose deliverable is one line in a pending `.changeset/*.md` carries a
hard deadline that nothing measured: once a release compiles the file into
`packages/<pkg>/CHANGELOG.md` the one-line edit is gone, while the card's prose
goes on asserting the file is "still pending" forever.

`scripts/pm/changeset-deadline-census.mjs` is the detection half, report-only:
it scans open issue BODIES for concrete `.changeset/<name>.md` paths and reports
each target's state on the ref. Presence is a LINE COUNT corroborated against a
single `.changeset/` listing — never an exit code, because `git ls-tree` exits 0
when nothing matches — and every run establishes a corpus, a positive and a
negative control before it judges a row, refusing outright when one fails. An
absent path is asked whether it ever landed, inside a history horizon proved per
row against the card's own filing date, so a shallow clone yields `inconclusive`
rather than a guess. The blind spots are printed by every run.

Nothing here fails a build: the new population is censused before anything is
enforced. Only the offline self-test runs in CI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 9, 2026
@github-actions github-actions Bot added size/l ci/cd dependencies Pull requests that update a dependency file labels Sep 9, 2026
@baozhoutao
baozhoutao marked this pull request as ready for review September 9, 2026 22:07
@baozhoutao
baozhoutao enabled auto-merge September 9, 2026 22:07
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 9, 2026
Merged via the queue into main with commit ae19f5e Sep 9, 2026
39 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-16850-changeset-deadline-census branch September 9, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants